package com.zxjbyte.yiyi.module.upms.manager;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.zxjbyte.yiyi.framework.common.util.CollXUtil;
import com.zxjbyte.yiyi.module.upms.domain.entity.UserPO;
import com.zxjbyte.yiyi.module.upms.service.UserService;
import com.zxjbyte.yiyi.module.upms.util.cache.HotUserCacheUtil;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户管理器
 *
 * @Author zhangxingjia
 * @Date 2024/9/13 10:05
 * @Version: 1.0
 */
@Component
public class UserManager {

    private static UserManager instance;
    @Resource
    private UserService userService;

    /**
     * 根据用户id获取用户信息
     * @param userId
     * @return
     */
    public UserPO getUserById(Long userId, boolean isHotCache){
        if(isHotCache){
            Map<Long, UserPO> map = listUsers(ImmutableSet.of(userId));
            if(CollUtil.isNotEmpty(map)){
                return map.get(userId);
            }
            return null;
        } else {
            return userService.getById(userId);
        }
    }

    public UserPO getUserById(Long userId){
        return getUserById(userId, true);
    }

    /**
     * 根据用户ID查询用户名称
     * @param userId
     * @return
     */
    public String getRealNameById(Long userId){
        UserPO userPo = getUserById(userId);
        return userPo != null ? userPo.getRealName() : null;
    }

    /**
     * 批量获取用户信息
     * @param userIds
     * @return
     */
    public Map<Long, UserPO> listUsers(Set<Long> userIds){
        if(CollXUtil.isEmpty(userIds)){
            return null;
        }
        // 优先缓存中获取
        Map<Long, UserPO> resultMap = Maps.newHashMap();
        Set<Long> notHitCacheUid = Sets.newHashSet();
        userIds.forEach(uid ->{
            UserPO userPo = HotUserCacheUtil.getIfPresent(uid);
            if(userPo != null){
                resultMap.put(uid, userPo);
            } else{
                notHitCacheUid.add(uid);
            }
        });
        if(notHitCacheUid.isEmpty()){
            return resultMap;
        }
        // 批量获取用户信息这里返回有用字段信息，优化查询
        LambdaQueryWrapper<UserPO> wrapper = Wrappers.lambdaQuery();
        if(notHitCacheUid.size() > 1){
            wrapper.in(UserPO::getId, notHitCacheUid);
        } else {
            wrapper.eq(UserPO::getId, notHitCacheUid.stream().iterator().next());
        }
        List<UserPO> list = userService.list(wrapper);
        Map<Long, UserPO> map = list.stream().collect(Collectors.toMap(UserPO::getId, Function.identity()));
        // 添加本地缓存
        map.forEach((k, v) -> {
            HotUserCacheUtil.put(k, v);
            resultMap.put(k, v);
        });
        return resultMap;
    }

    @PostConstruct
    public void init() {
        instance = this;
    }

    public static UserManager getInstance() {
        if (instance == null) {
            throw new IllegalStateException("UserManager not initialized yet");
        }
        return instance;
    }
}
